
#include "Result.h"
#include <map>



using namespace std;

static map<ErrorKind, string> g_presetErrorInfoMap = 
{
    { ErrorKind::Ok, ""},
    { ErrorKind::Unknown, "unknown error"},
    { ErrorKind::FileNotExist, "file is not exist"},
    { ErrorKind::DirNotExist, "directory is not exist"},
    { ErrorKind::InvalidOperation, "invalid operation"},
    { ErrorKind::ImcompleteIo, "input/output or receive/send imcomplete"},
    { ErrorKind::ExternalLibError, "calling external library and return an error"},
    { ErrorKind::OsRelatedError, "this is an operating system-related error"},
    { ErrorKind::IncorrectChecksum, "checksum is incorrect" },
    { ErrorKind::InvalidData, "invalid data" },
    { ErrorKind::InitFailed, "init failed" },
    { ErrorKind::ExecuteFailed, "execute failed" },
    { ErrorKind::Timeout, "timeout" },
    { ErrorKind::Busy, "busy" },
    { ErrorKind::InvalidArgument, "invalid argument" },
    { ErrorKind::OpenFailed, "open failed" },
    { ErrorKind::Receiving, "receiving" },
    { ErrorKind::NotPassiveMode, "not passive mode" },
    { ErrorKind::InvalidMessageReceiver, "invalid message receiver" },
};

Result Result::create(ErrorKind kind, const string &customizedInfo)noexcept 
{
    auto ins = Result();
    ins.m_kind = kind;
    if (true == customizedInfo.empty()) 
    {
        ins.m_message = g_presetErrorInfoMap[kind];
    }
    else 
    {
        ins.m_message = customizedInfo;
    }

    return ins;
}

Result::Result(ErrorKind kind) 
{
    m_kind = kind;
    // m_message = 0 != g_presetErrorInfoMap.count(kind) ? g_presetErrorInfoMap[kind] : "";
}

Result::Result(const Result &another)noexcept 
{
    m_kind = another.m_kind;
    m_message = another.m_message;
}

Result::Result(Result &&another)noexcept 
{
    m_kind = another.m_kind;
    m_message = std::move(another.m_message);
}

Result &Result::operator=(const Result &rhs)noexcept 
{
    m_kind = rhs.m_kind;
    m_message = rhs.m_message;

    return *this;
}

Result &Result::operator=(Result &&rhs)noexcept 
{
    m_kind = rhs.m_kind;
    m_message = std::move(rhs.m_message);

    return *this;
}

bool Result::operator==(const Result &rhs)const noexcept 
{
    return m_kind == rhs.m_kind && m_message == rhs.m_message;
}

bool Result::operator!=(const Result &rhs)const noexcept 
{
    return !(rhs == *this);
}

bool Result::isOk()const noexcept 
{
    return ErrorKind::Ok == m_kind;
}

Result::operator int()const noexcept 
{
    return this->code();
}

Result::operator string()const noexcept 
{
    return this->toString();
}

string Result::toString()const noexcept 
{
    if (true == this->isOk())
    {
        return m_message;
    }

    return m_message + ", error code: " + to_string(this->code());
}

void Result::appendInfo(const string &info) noexcept 
{
    if (true == this->isOk()) 
    {
        return;
    }

    m_message += ", ";
    m_message += info;
}

int Result::code()const noexcept 
{
     return static_cast<int>(m_kind);
}

const string &Result::message()const noexcept 
{
    return m_message;
}
